home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / ddj1190.arc / FBROWSE.PM < prev    next >
Text File  |  1990-10-27  |  17KB  |  519 lines

  1. ;********************************************************************
  2. ;*                                                                  *
  3. ;* PROT - A 386 protected mode DOS extender                         *
  4. ;* Copyright (C) 1989, by Al Williams                               *
  5. ;* All rights reserved.                                             *
  6. ;*                                                                  *
  7. ;* Permission is granted for non-commercial use of this software    *
  8. ;* subject to certain conditions (see PROT.ASM).                    *
  9. ;*                                                                  *
  10. ;* This file is: FBROWSE.PM, a file browser.                        *
  11. ;* To assemble: PMASM FBROWSE                                       *
  12. ;* or: MASM /DPROGRAM=FBROWSE PROT.ASM,FBROWSE.OBJ,FBROWSE.LST;     *
  13. ;*                                                                  *
  14. ;********************************************************************
  15.  
  16. ; If this equate is 0, use direct screen output else use DOS
  17. DOSOUT       EQU      0
  18.  
  19. ; This program displays a file. The file is stored as strings
  20. ; starting at the top of memory (the heap) and growing downward.
  21. ; At the start of memory is an array of pointers to lines in the
  22. ; heap.
  23.  
  24.  
  25.              PROT_DATA
  26. BASE         DD       0            ; top screen line
  27. PTRPTR       DD       0            ; pointer to end of line pointers
  28. HEAPPTR      DD       ?            ; pointer to empty heap entry
  29. FHANDLE      DW       ?            ; file handle
  30. LBUF         DB       81 DUP(?)    ; line buffer
  31. FBUFP        DD       0            ; pointer to character in fbuf
  32. FBUFL        DW       0            ; # of char's in fbuf
  33. FBUF         DB       512 DUP(?)   ; file buffer
  34. ; help message
  35. UMSG         DB       'Usage: FBROWSE filename',13,10,'$'
  36. ; error messages
  37. NFMSG        DB       'Can''t open file',13,10,'$'
  38. FEMSG        DB       'File error!',13,10,'$'
  39. OMMSG        DB       'Out of memory',13,10,'$'
  40. ; copyright message
  41. CPYMSG       DB       'FBROWSE - Protected Mode File Browser (C) 1989'
  42.              DB       ' by Al Williams'
  43. IF           DOSOUT
  44.              DB       '$'          ; end of string for DOS function 9
  45. ELSE
  46.              DB       0            ; end of string for PROT
  47. ENDIF
  48.  
  49. ; bios call frame
  50. BINTFRAME    VM86BLK  <>
  51.  
  52.              PROT_DATA_END
  53.  
  54.              PROT_CODE
  55. ; This routine catches ^BREAK's and forces program termination
  56. ONBREAK      PROC     FAR
  57.              MOV      AX,SEL_UDATA
  58.              MOV      DS,AX
  59.              JMP32S   USTOP0
  60. ONBREAK      ENDP
  61.  
  62. ; Main program
  63. USER         PROC     NEAR
  64. ; Enable Break handling
  65.              MOV      AX,SEL_UCODE
  66.              MOV      BRK_SEG,AX
  67.              MOV      EAX,OFFSET ONBREAK
  68.              MOV      BRK_OFF,EAX
  69. ; clear the screen
  70.              CALL32F  SEL_CODE32,CLS
  71. ; Set up CALL86 parameter blocks (pintframe & bintframe)
  72.              MOV      AX,SEG SSINT1
  73.              MOV      PINTFRAME.VMSS,EAX
  74.              MOV      BINTFRAME.VMSS,EAX
  75.              MOV      AX,SEG USERDATA
  76.              MOV      PINTFRAME.VMDS,EAX
  77.              MOV      EAX, OFFSET SSINT1
  78.              MOV      PINTFRAME.VMESP,EAX
  79.              MOV      BINTFRAME.VMESP,EAX
  80. ; Pintframe will be used for INT 21
  81.              MOV      EAX,21H
  82.              MOV      PINTFRAME.VMINT,EAX
  83. ; get command line
  84.              MOV      CX,SEL_PSP
  85.              MOV      FS,CX
  86.              ASSUME   FS:NOTHING
  87.              XOR      EBX,EBX
  88.              MOV      BL,FS:[80H]
  89.              OR       BL,BL
  90.              JNZ      SHORT OPENFILE
  91. ; No command line - Print usage message
  92.              MOV      AH,9
  93.              MOV      EDX,OFFSET UMSG
  94.              MOV      EBX,OFFSET PINTFRAME
  95.              VM86CALL
  96.              MOV      AL,1
  97.              JMP32S   USTOP        ; back to DOS
  98. ; Open file for reading
  99. OPENFILE:
  100.              XOR      AX,AX        ; null terminate file name
  101.              MOV      FS:[81H+BX],AX
  102.              MOV      AX,_PSP
  103.              MOV      PINTFRAME.VMDS,EAX
  104.              MOV      EDX,80H
  105. ; skip spaces
  106. SPACSKIP:
  107.              INC      DX
  108.              CMP      BYTE PTR FS:[EDX],' '
  109.              JZ       SHORT SPACSKIP
  110.              MOV      AX,3D00H
  111.              MOV      EBX,OFFSET PINTFRAME
  112.              VM86CALL              ; open file
  113.              MOV      BX,SEG USERDATA
  114.              MOV      PINTFRAME.VMDS,EBX
  115.              JNC      SHORT FOPENED
  116. ; Couldn't open file -- print error
  117.              MOV      EDX,OFFSET NFMSG
  118.              MOV      AH,9
  119.              MOV      EBX,OFFSET PINTFRAME
  120.              VM86CALL              ; can't open file
  121.              MOV      AL,1
  122.              JMP32S   USTOP        ; back to DOS
  123. ; File opened OK
  124. FOPENED:
  125.              MOV      FHANDLE,AX   ; save file handle
  126. ; See if extended memory present
  127.              MOV      AX,SEL_EXT
  128.              LSL      EBX,EAX
  129.              OR       EBX,EBX
  130.              JNZ      SHORT USE_EXTMEM
  131. ; No extended memory present -- use DOS memory
  132.              MOV      AX,SEL_FREE
  133. USE_EXTMEM:
  134.              MOV      GS,AX        ; memory segment --> GS
  135. ; Set heap pointer to top of availble memory
  136.              LSL      EAX,EAX
  137.              MOV      HEAPPTR,EAX
  138.              MOV      EDX,EAX
  139.              XOR      EBX,EBX
  140. REREAD:
  141.              MOV      EAX,EBX      ; check for heap overflow
  142.              SHL      EAX,2
  143.              CMP      EAX,EDX
  144.              JB       SHORT HEAPOK
  145. ; No more memory -- Print error message
  146.              MOV      AH,9
  147.              MOV      EDX,OFFSET OMMSG
  148.              MOV      EBX,OFFSET PINTFRAME
  149.              VM86CALL              ; out of memory
  150.              MOV      AL,1
  151.              JMP32S   USTOP        ; back to DOS
  152. HEAPOK:
  153. ; Put heap pointer in lines array
  154.              MOV      GS:[EBX*4],EDX
  155. ; read line to heap in reverse order. Each line ends in CR
  156.              CALL     SHORT READLINE
  157.              PUSHFD
  158. ; point to next line in lines array
  159.              INC      EBX
  160.              POPFD
  161.              JNZ      SHORT REREAD ; not end of file?
  162. ; here at end of file
  163.              MOV      PTRPTR,EBX   ; end of lines array
  164.              MOV      BX,FHANDLE
  165.              MOV      PINTFRAME.VMEBX,EBX
  166.              MOV      AH,3EH
  167.              MOV      EBX,OFFSET PINTFRAME
  168.              VM86CALL              ; close file
  169.              MOV      DX,1800H
  170.              CALL     SHORT SETCP  ; set cursor position
  171. ; write copyright message
  172. IF           DOSOUT
  173.              MOV      AH,9
  174.              MOV      EDX,OFFSET CPYMSG
  175.              MOV      EBX,OFFSET PINTFRAME
  176.              VM86CALL              ; print copyright
  177. ELSE
  178. ; If not BIOS output then get rid of BIOS cursor
  179.              MOV      DX,0FFFFH
  180.              CALL32S  DOSSETCP     ; hide cursor
  181.              MOV      EBX,OFFSET CPYMSG
  182.              CALL32F  SEL_CODE32,MESSOUT
  183. ENDIF
  184.  
  185.  
  186. ; inverse video the bottom line
  187.              PUSH     DS
  188.              MOV      AX,SEL_VIDEO
  189.              MOV      DS,AX
  190.              MOV      CL,80
  191.              MOV      EDX,24*160+1 ; bottom line
  192. INVLOOP:
  193.              MOV      BYTE PTR [EDX],70H
  194.              INC      EDX
  195.              INC      EDX
  196.              DEC      CL
  197.              JNZ      SHORT INVLOOP
  198.              POP      DS
  199.              JMP      SHORT HK0    ; skip over home key processing
  200. ; Home key processing
  201. HOMEKEY:     OR       BASE,0       ; don't do home if already there
  202.              JZ       SHORT KEYLOOP
  203. HK0:
  204.              XOR      EAX,EAX      ; Set screen start to 0
  205.              MOV      BASE,EAX
  206. ; Come here to display a page starting at base
  207. PAGEDISP:
  208.              CALL     SHORT DISPLAY
  209. ; read a key and act on it
  210. KEYLOOP:     MOV      AX,16H
  211.              MOV      BINTFRAME.VMINT,EAX
  212.              XOR      AH,AH
  213.              PUSH     ES
  214.              MOV      BX,SEL_UDATA
  215.              MOV      ES,BX
  216.              MOV      EBX,OFFSET BINTFRAME
  217.              VM86CALL              ; read a key
  218.              POP      ES
  219.              CMP      AL,27        ; escape key?
  220.              JZ       NEAR PTR USTOP0
  221.              CMP      AL,3         ; break key
  222.              JZ       NEAR PTR USTOP0
  223.              OR       AL,AL
  224.              JNZ      SHORT KEYERR ; special key?
  225. ; test for function keys
  226.              CMP      AH,48H       ; up arrow
  227.              JCC32    Z, UPARROW
  228.              CMP      AH,47H       ; home key
  229.              JZ       SHORT HOMEKEY
  230.              CMP      AH,4FH       ; end key
  231.              JCC32    Z,ENDKEY
  232.              CMP      AH,49H       ; page up
  233.              JCC32    Z,PGUP
  234.              CMP      AH,51H       ; page down
  235.              JCC32    Z,PGDN
  236.              CMP      AH,50H       ; down arrow
  237.              JZ       SHORT DNARROW
  238. ; Come here if you don't know what that key was!
  239. KEYERR:
  240.              PUSH     EDX
  241.              MOV      DL,7         ; bell character
  242.              MOV      AH,2
  243.              MOV      EBX,OFFSET PINTFRAME
  244.              VM86CALL
  245.              POP      EDX
  246.              JMP      SHORT KEYLOOP
  247.  
  248. ; down arrow processing
  249. DNARROW:
  250.              MOV      EAX,BASE     ; don't go down if at end
  251.              ADD      EAX,24
  252.              CMP      EAX,PTRPTR
  253.              JCC32    AE,KEYLOOP
  254.              INC      BASE         ; top of screen + 1
  255.              MOV      AX,0601H     ; scroll screen
  256.              CALL     SHORT SCROLL
  257.              MOV      DX,1700H     ; position cursor
  258.              CALL     SHORT SETCP
  259.              MOV      EDX,BASE     ; print bottom line
  260.              ADD      EDX,23
  261.              CALL     SHORT PLINE
  262.              JMP32S   KEYLOOP
  263.  
  264. ; up arrow processing
  265. UPARROW:
  266.              OR       BASE,0       ; don't go up if at top
  267.              JCC32    Z,KEYLOOP
  268.              DEC      BASE         ; adjust top of screen
  269.              MOV      AX,0701H     ; scroll screen
  270.              CALL     SHORT SCROLL
  271.              XOR      DX,DX        ; position cursor
  272.              CALL     SHORT SETCP
  273.              MOV      EDX,BASE     ; print top line
  274.              CALL     SHORT PLINE
  275.              JMP32S   KEYLOOP
  276.  
  277. ; End key processing
  278. ENDKEY:      MOV      EAX,BASE     ; Don't do end if already there
  279.              ADD      EAX,24
  280.              CMP      EAX,PTRPTR
  281.              JCC32    AE,KEYLOOP
  282.              MOV      EAX,PTRPTR   ; get last line
  283.              SUB      EAX,24       ; find top of screen
  284.              MOV      BASE,EAX
  285.              JMP32S   PAGEDISP     ; display page
  286.  
  287.  
  288. ; Page Up processing
  289. PGUP:        MOV      EAX,BASE     ; Don't do pgup if at top
  290.              OR       EAX,EAX
  291.              JCC32    Z,KEYLOOP
  292.              CMP      EAX,24
  293.              JBE      SHORT PGUP0  ; if near the top.. go pgup0
  294.              SUB      EAX,24       ; find new line
  295.              JMP      SHORT PGUP1
  296. PGUP0:       XOR      EAX,EAX      ; 1st line
  297. PGUP1:       MOV      BASE,EAX
  298.              JMP32S   PAGEDISP
  299.  
  300. ; Page down processing
  301. PGDN:        MOV      EAX,BASE     ; If at bottom, skip
  302.              ADD      EAX,24
  303.              CMP      EAX,PTRPTR
  304.              JCC32    AE,KEYLOOP
  305.              MOV      BASE,EAX     ; find new line
  306.              JMP32S   PAGEDISP
  307.  
  308.  
  309.  
  310. ; Exit FBROWSE
  311. USTOP0:
  312. ; clear screen
  313.              CALL32F  SEL_CODE32,CLS
  314.              XOR      AL,AL        ; zero return code
  315.              PUSH     EAX
  316.              XOR      DX,DX        ; home cursor
  317.              CALL     SHORT DOSSETCP
  318.              POP      EAX
  319. USTOP:
  320.              BACK2DOS
  321.  
  322. USER         ENDP
  323.  
  324. ; Read a line from the file
  325. ; lines end in 0AH unless they are long in which case they
  326. ; end in 0DH
  327. READLINE     PROC     NEAR
  328.              PUSH     ECX
  329.              MOV      CX,80
  330. RLINE0:
  331.              CALL     SHORT GFCHAR ; get character
  332.              MOV      GS:[EDX],AL  ; store it
  333.              PUSHFD
  334.              DEC      EDX
  335.              POPFD                 ; end of line?
  336.              JZ       SHORT RLINEXIT
  337.              CMP      AL,0AH       ; end of line?
  338.              JZ       SHORT RLINEEOL
  339.              DEC      CX
  340.              JNZ      SHORT RLINE0 ; 80 char line?
  341. ; compare last character with 0ah  -- if true pass it
  342.              CALL     SHORT GFCHAR
  343.              CMP      AL,0AH
  344. ; if so, line exactly 80 chars
  345.              JZ       SHORT LONGLINE
  346.              DEC      FBUFP        ; unget character
  347. LONGLINE:
  348.              MOV      AL,0DH       ; mark long line
  349.              MOV      GS:[EDX],AL  ; save end marker
  350.              DEC      EDX
  351. RLINEEOL:    CMP      AL,0FFH      ; set NZ flag
  352. RLINEXIT:
  353.              POP      ECX
  354.              RET
  355. READLINE     ENDP
  356.  
  357. ; scroll screen using BIOS
  358. SCROLL       PROC     NEAR
  359.              PUSH     ES
  360.              MOV      BX,SEL_UDATA
  361.              MOV      ES,BX
  362.              MOV      BX,0700H
  363.              MOV      BINTFRAME.VMEBX,EBX
  364.              MOV      BX,10H
  365.              MOV      BINTFRAME.VMINT,EBX
  366.              XOR      ECX,ECX
  367.              MOV      DX,174FH
  368.              MOV      EBX,OFFSET BINTFRAME
  369.              VM86CALL
  370.              POP      ES
  371.              RET
  372. SCROLL       ENDP
  373.  
  374. ; position the cursor
  375. DOSSETCP     PROC     NEAR
  376.              PUSH     EBX
  377.              PUSH     ES
  378.              MOV      AX,SEL_UDATA
  379.              MOV      ES,AX
  380.              MOV      BX,10H
  381.              MOV      BINTFRAME.VMINT,EBX
  382.              MOV      BINTFRAME.VMEBX,EBX
  383.              MOV      AH,2
  384.              MOV      EBX,OFFSET BINTFRAME
  385.              VM86CALL
  386.              POP      ES
  387.              POP      EBX
  388.              RET
  389. DOSSETCP     ENDP
  390.  
  391. SETCP        PROC     NEAR
  392. IF           DOSOUT
  393.              CALL32S  DOSSETCP
  394. ELSE
  395.              PUSH     ES
  396.              MOV      AX,SEL_DATA
  397.              MOV      ES,AX
  398.              MOV      EAX,80
  399.              MUL      DH
  400.              XOR      DH,DH
  401.              ADD      AX,DX
  402.              MOV      ES:CURSOR,EAX
  403.              POP      ES
  404.              RET
  405. ENDIF
  406. SETCP        ENDP
  407.  
  408.  
  409. ; display a screen full
  410. DISPLAY      PROC     NEAR
  411.              MOV      AX,0600H
  412.              CALL32S  SCROLL       ; clear screen
  413.              XOR      DX,DX
  414.              CALL32S  SETCP        ; home cursor
  415.              MOV      CX,24
  416.              MOV      EDX,BASE
  417. DISP0:
  418.              PUSH     EDX
  419.              CALL     SHORT PLINE  ; print lines
  420.              POP      EDX
  421.              INC      EDX
  422.              CMP      EDX,PTRPTR
  423.              JZ       DISP00
  424.              DEC      CX
  425.              JNZ      SHORT DISP0
  426. DISP00:
  427.              RET
  428. DISPLAY      ENDP
  429.  
  430. ; print a line pointed to by [edx] going backwards to \n
  431. PLINE        PROC     NEAR
  432. ; get line ptr
  433.              MOV      EDX,GS:[EDX*4]
  434. PLINE0:
  435.              MOV      AL,GS:[EDX]  ; get char fm str
  436.              DEC      DX
  437.              CMP      AL,0DH       ; Long line?
  438.              JZ       SHORT PLINE2
  439.              CALL     SHORT OOUCH  ; Output character
  440.              CMP      AL,0AH       ; End of string
  441.              JNZ      SHORT PLINE0
  442. PLINE1:
  443.              MOV      AL,0DH       ; Output CR
  444.              CALL     SHORT OOUCH
  445. PLINE2:
  446.              RET
  447. PLINE        ENDP
  448.  
  449.  
  450. ; get a character from the file
  451. GFCHAR       PROC     NEAR
  452.              PUSH     EBX
  453.              PUSH     EDX
  454.              PUSH     ECX
  455. GFSKIP:
  456.              OR       FBUFL,0      ; buffer empty?
  457.              JZ       SHORT FILLBUFF
  458.              MOV      EAX,FBUFP    ; buffer used up?
  459.              CMP      AX,FBUFL
  460.              JNZ      SHORT FMBUFF
  461. FILLBUFF:
  462.              MOV      AX,FHANDLE   ; read from file
  463.              MOV      PINTFRAME.VMEBX,EAX
  464.              MOV      ECX,512
  465.              MOV      EDX,OFFSET FBUF
  466.              MOV      AH,3FH
  467.              MOV      EBX,OFFSET PINTFRAME
  468.              VM86CALL              ; read buffer
  469.              JNC      SHORT NOFERR
  470. ; file error here
  471.              MOV      AH,9
  472.              MOV      EDX,OFFSET FEMSG
  473.              VM86CALL
  474.              JMP32S   USTOP        ; back to DOS
  475. NOFERR:      OR       AX,AX
  476.              MOV      FBUFL,AX     ; store buffer length
  477.              MOV      AL,0AH
  478.              JZ       SHORT GFCEOF ; End of file?
  479.              XOR      EAX,EAX      ; clear buffer pointer
  480.              MOV      FBUFP,EAX
  481. ; This is where the character is read from a good buffer
  482. FMBUFF:
  483.              MOV      EBX,FBUFP
  484.              MOV      AL,FBUF[EBX]
  485.              INC      EBX
  486.              MOV      FBUFP,EBX
  487.              CMP      AL,0DH       ; skip CR
  488.              JCC32    Z,GFSKIP
  489. GFCEOF:
  490.              POP      ECX
  491.              POP      EDX
  492.              POP      EBX
  493.              RET
  494. GFCHAR       ENDP
  495.  
  496. ; output character in al
  497. OOUCH        PROC     NEAR
  498. IF           DOSOUT
  499.              PUSHAD
  500.              PUSH     ES
  501.              ASSUME   ES:DAT32
  502.              MOV      BX,SEL_DATA
  503.              MOV      ES,BX
  504.              MOV      AH,2
  505.              MOV      DL,AL
  506.              MOV      EBX,OFFSET PINTFRAME
  507.              VM86CALL
  508.              POP      ES
  509.              POPAD
  510.              RET
  511. ELSE
  512.              CALL32F  SEL_CODE32,OUCH
  513.              RET
  514. ENDIF
  515. OOUCH        ENDP
  516.  
  517.  
  518.              PROT_CODE_END
  519.